package van.planifolia.redislock.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import van.planifolia.redislock.dao.GoodsDao;
import van.planifolia.redislock.pojo.Goods;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO
 * @Author: Van.Planifolia
 * @CreateTime: 2022-12-08  10:21
 * @Version: 1.0
 */
@Service("goodsService")
public class GoodsService {
    @Resource
    private GoodsDao goodsDao;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public String saleGoods(Integer id) {
        // 使用Redis上锁
        Boolean locked = stringRedisTemplate.opsForValue().setIfAbsent("goodsLock::" + id, "locked", 30, TimeUnit.SECONDS);
        // 若上锁成功了就执行下面的业务代码,我们必须把判断写在try最外面，否则finally在或缺锁失败的时候也会执行
        if (Boolean.TRUE.equals(locked)) {
            try {
                // 判断商品数量是否合格
                Goods goods = goodsDao.selectById(id);
                if (goods.getNub() > 0) {
                    goods.setNub(goods.getNub() - 1);
                    // 然后更新数据库
                    goodsDao.updateById(goods);
                    System.out.println("成功卖出一张票,还剩下：" + goods.getNub() + "张");
                    return "售卖成功,还剩下" + goods.getNub() + "张";
                }
                System.out.println("票数不足");
                return "售卖失败，票数不足";

                // 无论结果如何要在finally中解锁
            } finally {
                stringRedisTemplate.delete("goodsLock::" + id);
            }
        } else {
            // 若上锁失败就提示程序忙
            System.out.println("程序正忙");
            return "程序正忙";
        }

    }
}
